iT邦幫忙

0

在 C# 中 Nullable Reference Types 使用屬性NotNullWhen

c#
  • 分享至 

  • xImage
  •  

承上文 在 C# 中 Nullable Reference Types 使用屬性AllowNull

繼續探討...

使用屬性 NotNullWhen

假設我們有一個方法檢查變數是否為 null。根據此檢查的結果,該方法返回 bool 類型的值。

示例:

bool CheckNotNull(object? obj)
{
  return obj != null;
}

使用此方法:

public void Foo(object? obj1)
{
  object obj2 = new object();

  if (CheckNotNull(obj1))
    obj2 = obj1;
}

編譯器將對上面的程式碼發出警告:
https://ithelp.ithome.com.tw/upload/images/20230105/201525691bHAzODIWH.jpg

警告訊息如下:

警告	CS8600	正在將 Null 常值或可能的 Null 值轉換為不可為 Null 的型別。		

但這段程式碼NULL情況是不可能發生的,因為已經先檢查確保不為空。問題是編譯器無法理解這個情況,所以我們必須幫助它。

我們可以加入屬性 NotNullWhen 來更改 CheckNotNull() 的簽名:

bool CheckNotNull([NotNullWhen(true)]object? obj)

此屬性將將參數的 Null 狀態與 檢查方法的回傳值 相關聯。
用來向編譯器“解釋”,如果方法返回 true,則該參數 obj 具有值非空。


這個NotNullWhen 屬性還有一些特性如下:

若使用out修飾符

bool GetValidOrDefaultName([NotNullWhen(true)] out string? validOrDefaultName, 
                           string name)
{
  if (name == null)
  {
    validOrDefaultName = name;
    return true;
  }
  else
  {
    validOrDefaultName = "defaultName";
    return false;
  }
}

編譯器將對上面的程式碼發出警告:
https://ithelp.ithome.com.tw/upload/images/20230105/20152569X9VYLsxsrd.jpg

警告訊息如下:

警告	CS8762	參數 'validOrDefaultName' 在以 'true' 結束時必須具有非 Null 值。		

這裡警告非常合理,因為你用了NotNullWhen屬性向編譯器“解釋”,
如果方法返回 true,則該參數 validOrDefaultName 具有值非空。
但在此段程式碼中,當 validOrDefaultName 為 null 時,該方法返回 true。
除非你在條件中使用了 “!=” 而不是 “==” 運算符


若使用ref修飾符

bool SetDefaultIfNotValid([NotNullWhen(true)] ref string? name)
{
  if (name == null)
    return true;

  name = "defaultName";
  return false;
}

編譯器將對上面的程式碼發出警告:
https://ithelp.ithome.com.tw/upload/images/20230105/20152569AeEYUFsnP7.jpg

警告訊息如下:

警告	CS8762	參數 'name' 在以 'true' 結束時必須具有非 Null 值。		

與前面的例子類似,這裡警告非常合理,因為你用了NotNullWhen屬性向編譯器“解釋”,
如果方法返回 true,則該參數 name 具有值非空。
因為你使用了 '==' 而不是 '!=' 運算符。


若不使用修飾符

bool CheckingForNull([NotNullWhen(true)] string? name)
{
  if (name == null)
    return true;

  Console.WriteLine("name is null");
  return false;
}

這裡的情況與之前的案例類似。按照前面例子的邏輯,這裡應該也發出警告訊息:

Parameter 'name' must have a non-null value when exiting with 'true'。

但是,沒有警告。
https://ithelp.ithome.com.tw/upload/images/20230105/20152569GLUSay25sa.jpg
微軟這樣的邏輯其實很怪。 WHY???
什麼原因造成的? 不好說~

也許這裡就是所謂一些不顯而易見的地方

了解更多:NotNullWhenAttribute Class


下一篇
在 C# 中 Nullable Reference Types 使用屬性NotNullIfNotNull


圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言